package com.gzc.just.play.last.war.centralserver.team;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 队伍管理器 - 管理所有队伍
 * 
 * @author AI编程助手
 * @version 1.0
 */
public class TeamManager {
    
    private final Map<Long, Team> teams = new ConcurrentHashMap<>();
    private final Map<Long, Long> playerTeams = new ConcurrentHashMap<>(); // playerId -> teamId
    private final Map<Long, List<TeamInvitation>> pendingInvitations = new ConcurrentHashMap<>();
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final AtomicLong teamIdGenerator = new AtomicLong(1000);
    private final AtomicLong invitationIdGenerator = new AtomicLong(1);
    private final List<TeamListener> listeners = new CopyOnWriteArrayList<>();
    
    /**
     * 创建新队伍
     * 
     * @param teamName 队伍名称
     * @param leaderId 队伍领导者ID
     * @param leaderName 队伍领导者名称
     * @return 新创建的队伍
     */
    public Team createTeam(String teamName, long leaderId, String leaderName) {
        lock.writeLock().lock();
        try {
            // 检查玩家是否已有队伍
            if (playerTeams.containsKey(leaderId)) {
                return null;
            }
            
            long teamId = teamIdGenerator.incrementAndGet();
            Team team = new Team(teamId, teamName, leaderId, leaderName);
            
            teams.put(teamId, team);
            playerTeams.put(leaderId, teamId);
            
            notifyTeamCreated(team);
            return team;
        } finally {
            lock.writeLock().unlock();
        }
    }
    
    /**
     * 获取队伍
     * 
     * @param teamId 队伍ID
     * @return 队伍对象
     */
    public Team getTeam(long teamId) {
        lock.readLock().lock();
        try {
            return teams.get(teamId);
        } finally {
            lock.readLock().unlock();
        }
    }
    
    /**
     * 获取玩家所在的队伍
     * 
     * @param playerId 玩家ID
     * @return 队伍对象，如果玩家不在任何队伍中则返回null
     */
    public Team getPlayerTeam(long playerId) {
        Long teamId = playerTeams.get(playerId);
        if (teamId != null) {
            return getTeam(teamId);
        }
        return null;
    }
    
    /**
     * 邀请玩家加入队伍
     * 
     * @param teamId 队伍ID
     * @param inviterId 邀请者ID
     * @param inviteeId 被邀请者ID
     * @return 邀请对象
     */
    public TeamInvitation invitePlayer(long teamId, long inviterId, long inviteeId) {
        lock.writeLock().lock();
        try {
            Team team = teams.get(teamId);
            if (team == null || team.isFull() || playerTeams.containsKey(inviteeId)) {
                return null;
            }
            
            long invitationId = invitationIdGenerator.incrementAndGet();
            TeamInvitation invitation = new TeamInvitation(invitationId, teamId, inviterId, inviteeId);
            
            List<TeamInvitation> invitations = pendingInvitations.computeIfAbsent(inviteeId, k -> new CopyOnWriteArrayList<>());
            invitations.add(invitation);
            
            notifyInvitationSent(invitation);
            return invitation;
        } finally {
            lock.writeLock().unlock();
        }
    }
    
    /**
     * 获取玩家的待处理邀请
     * 
     * @param playerId 玩家ID
     * @return 邀请列表
     */
    public List<TeamInvitation> getPendingInvitations(long playerId) {
        lock.readLock().lock();
        try {
            List<TeamInvitation> invitations = pendingInvitations.get(playerId);
            if (invitations != null) {
                return new ArrayList<>(invitations);
            }
            return new ArrayList<>();
        } finally {
            lock.readLock().unlock();
        }
    }
    
    /**
     * 接受队伍邀请
     * 
     * @param invitationId 邀请ID
     * @param playerId 玩家ID
     * @return 是否成功接受
     */
    public boolean acceptInvitation(long invitationId, long playerId) {
        lock.writeLock().lock();
        try {
            List<TeamInvitation> invitations = pendingInvitations.get(playerId);
            if (invitations == null) {
                return false;
            }
            
            TeamInvitation invitation = null;
            for (TeamInvitation inv : invitations) {
                if (inv.getInvitationId() == invitationId) {
                    invitation = inv;
                    break;
                }
            }
            
            if (invitation == null || !invitation.accept()) {
                return false;
            }
            
            Team team = teams.get(invitation.getTeamId());
            if (team != null && team.addMember(playerId, "Player" + playerId, Team.TeamRole.MEMBER)) {
                playerTeams.put(playerId, team.getTeamId());
                invitations.remove(invitation);
                notifyPlayerJoinedTeam(team, playerId);
                return true;
            }
            
            return false;
        } finally {
            lock.writeLock().unlock();
        }
    }
    
    /**
     * 拒绝队伍邀请
     * 
     * @param invitationId 邀请ID
     * @param playerId 玩家ID
     * @return 是否成功拒绝
     */
    public boolean rejectInvitation(long invitationId, long playerId) {
        lock.writeLock().lock();
        try {
            List<TeamInvitation> invitations = pendingInvitations.get(playerId);
            if (invitations == null) {
                return false;
            }
            
            for (TeamInvitation invitation : invitations) {
                if (invitation.getInvitationId() == invitationId && invitation.reject()) {
                    invitations.remove(invitation);
                    return true;
                }
            }
            return false;
        } finally {
            lock.writeLock().unlock();
        }
    }
    
    /**
     * 玩家离开队伍
     * 
     * @param playerId 玩家ID
     * @return 是否成功离开
     */
    public boolean leaveTeam(long playerId) {
        lock.writeLock().lock();
        try {
            Long teamId = playerTeams.remove(playerId);
            if (teamId != null) {
                Team team = teams.get(teamId);
                if (team != null) {
                    // 如果是队长离开，解散队伍或转移权限
                    if (team.getLeaderId() == playerId) {
                        // 简单处理：队长离开则解散队伍
                        teams.remove(teamId);
                        for (Team.TeamMember member : team.getMembers()) {
                            playerTeams.remove(member.playerId);
                        }
                        notifyTeamDisbanded(team);
                    } else {
                        team.removeMember(playerId);
                        notifyPlayerLeftTeam(team, playerId);
                    }
                    return true;
                }
            }
            return false;
        } finally {
            lock.writeLock().unlock();
        }
    }
    
    /**
     * 获取所有队伍（仅开放的）
     * 
     * @return 队伍列表
     */
    public List<Team> getOpenTeams() {
        lock.readLock().lock();
        try {
            List<Team> openTeams = new ArrayList<>();
            for (Team team : teams.values()) {
                if (team.isOpen() && !team.isFull()) {
                    openTeams.add(team);
                }
            }
            return openTeams;
        } finally {
            lock.readLock().unlock();
        }
    }
    
    /**
     * 获取队伍总数
     * 
     * @return 队伍数
     */
    public int getTeamCount() {
        return teams.size();
    }
    
    /**
     * 添加监听器
     * 
     * @param listener 监听器
     */
    public void addListener(TeamListener listener) {
        if (listener != null) {
            listeners.add(listener);
        }
    }
    
    /**
     * 移除监听器
     * 
     * @param listener 监听器
     */
    public void removeListener(TeamListener listener) {
        listeners.remove(listener);
    }
    
    private void notifyTeamCreated(Team team) {
        for (TeamListener listener : listeners) {
            listener.onTeamCreated(team);
        }
    }
    
    private void notifyTeamDisbanded(Team team) {
        for (TeamListener listener : listeners) {
            listener.onTeamDisbanded(team);
        }
    }
    
    private void notifyInvitationSent(TeamInvitation invitation) {
        for (TeamListener listener : listeners) {
            listener.onInvitationSent(invitation);
        }
    }
    
    private void notifyPlayerJoinedTeam(Team team, long playerId) {
        for (TeamListener listener : listeners) {
            listener.onPlayerJoinedTeam(team, playerId);
        }
    }
    
    private void notifyPlayerLeftTeam(Team team, long playerId) {
        for (TeamListener listener : listeners) {
            listener.onPlayerLeftTeam(team, playerId);
        }
    }
    
    /**
     * 队伍监听器接口
     */
    public interface TeamListener {
        void onTeamCreated(Team team);
        void onTeamDisbanded(Team team);
        void onInvitationSent(TeamInvitation invitation);
        void onPlayerJoinedTeam(Team team, long playerId);
        void onPlayerLeftTeam(Team team, long playerId);
    }
}
